#pragma once
#ifndef _GEOMETRY_2D_SEGMENT_
#define _GEOMETRY_2D_SEGMENT_

//================================================================================================================================
//================================================================================================================================
// Локальные
#include "math/math.h"
#include "geometry/2d/point.h"
#include "core_global.h"

//================================================================================================================================
//================================================================================================================================
namespace geometry
{
    namespace _2d
    {
        /// \brief Отрезок в двумерном пространстве.
        /// \remarks Отрезок ориентирован в пространстве. Одна из его точек рассматривается как начало, вторая - как конец.
        class CORE_EXPORT Segment
        {
        public:
            /// Создание отрезка с началом в точке (0;0) и концом в точке (1;1).
            Segment() : m_Begin(0.0, 0.0), m_End(1.0, 1.0) {}

            /// Создание отрезка с началом и концом в указанных точках.
            Segment(const Point &begin, const Point &end) : m_Begin(begin), m_End(end) {}

            /// Развернуть отрезок в пространстве (поменять местами первую и последнюю точки).
            void swap()
            {
                Point temp = m_Begin;
                m_Begin = m_End;
                m_End = temp;
            }

            /// Длина отрезка
            double length() const {return qSqrt(math::square(m_End.x() - m_Begin.x()) + math::square(m_End.y() - m_Begin.y()));}

            /// Получение конечной точки отрезка.
            Point end() const {return m_End;}

            /// Получение начальной точки отрезка.
            Point begin() const {return m_Begin;}

            /// Изменение конечной точки отрезка.
            void setEnd(const Point &end) {m_End = end;}

            /// Изменение начальной точки отрезка.
            void setBegin(const Point &begin) {m_Begin = begin;}

        private:
            Point m_Begin;  ///< Начальная точка отрезка.
            Point m_End;    ///< Конечная точка отрезка.
        };

        //========================================================================================================================
        //========================================================================================================================
        /// Сравнение отрезков.
        /// \relates Segment
        /// \remarks При сравнении учитывается направление отрезков.
        inline bool operator==(const Segment &s1, const Segment &s2){return s1.begin() == s2.begin() && s1.end() == s2.end();}

        /// Сравнение отрезков.
        /// \relates Segment
        /// \remarks При сравнении учитывается направление отрезков.
        inline bool operator!=(const Segment &s1, const Segment &s2){return s1.begin() != s2.begin() || s1.end() != s2.end();}
    }
}

#endif // _GEOMETRY_2D_SEGMENT_
